package com.lovezy.platform.play.scene.service.impl;

import com.github.pagehelper.Page;
import com.lovezy.platform.core.base.query.Pager;
import com.lovezy.platform.core.base.service.MapperService;
import com.lovezy.platform.core.exception.ServiceException;
import com.lovezy.platform.core.utils.ArrayUtil;
import com.lovezy.platform.play.model.PlayCharacter;
import com.lovezy.platform.play.scene.mapper.PlaySceneCharacterMapper;
import com.lovezy.platform.play.scene.model.PlaySceneCharacter;
import com.lovezy.platform.play.scene.model.PlaySceneCharacterExample;
import com.lovezy.platform.play.scene.vo.CharacterData;
import com.lovezy.platform.play.scene.vo.ItemSimpleInfo;
import com.lovezy.platform.play.scene.vo.SimpleCharacterMeta;
import com.lovezy.platform.play.scene.vo.SkillSimpleInfo;
import com.lovezy.platform.play.service.PlayCharacterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

import static java.util.stream.Collectors.toList;

/**
 * Created by jin on 2018/1/30.
 */
@Service
public class PlaySceneCharacterService extends MapperService<PlaySceneCharacter,Integer,PlaySceneCharacterMapper>{

    @Autowired
    PlayCharacterService playCharacterService;

    @Autowired
    PlaySceneCharacterSkillService playSceneCharacterSkillService;

    @Autowired
    PlaySceneCharacterItemService playSceneCharacterItemService;

    public PlaySceneCharacter findCharacter(Integer sceneId, String mid) {
        PlaySceneCharacterExample example = new PlaySceneCharacterExample();
        example.createCriteria()
                .andSceneIdEqualTo(sceneId)
                .andMemberIdEqualTo(mid);
        Optional<PlaySceneCharacter> sceneCharacterOptional = Pager.doSingleton(() -> mapper.selectByExample(example));
        if (!sceneCharacterOptional.isPresent()) {
            throw new ServiceException("未找到您的角色");
        }
        return sceneCharacterOptional.get();
    }

    public PlaySceneCharacter findCharacter(Integer sceneId, Integer characterId) {
        PlaySceneCharacterExample example = new PlaySceneCharacterExample();
        example.createCriteria()
                .andSceneIdEqualTo(sceneId)
                .andCharacterIdEqualTo(characterId);
        Optional<PlaySceneCharacter> sceneCharacterOptional = Pager.doSingleton(() -> mapper.selectByExample(example));
        if (!sceneCharacterOptional.isPresent()) {
            throw new ServiceException("未找到此角色");
        }
        return sceneCharacterOptional.get();
    }

    public List<PlaySceneCharacter> findAllSceneCharacters(Integer sceneId) {
        PlaySceneCharacterExample example = new PlaySceneCharacterExample();
        example.createCriteria()
                .andSceneIdEqualTo(sceneId);
        return Pager.doPageAll(() -> mapper.selectByExample(example));
    }

    public List<CharacterData> findAllCharacterFullInfo(Integer sceneId) {
        List<PlaySceneCharacter> characters = findAllSceneCharacters(sceneId);
        return characters.stream()
                .map(this::characterWithFullData)
                .collect(toList());
    }

    public CharacterData findCharacterDateByMemberId(Integer sceneId, String mid) {
        PlaySceneCharacterExample example = new PlaySceneCharacterExample();
        example.createCriteria()
                .andSceneIdEqualTo(sceneId)
                .andMemberIdEqualTo(mid);
        Optional<PlaySceneCharacter> characterOptional = Pager.doSingleton(() -> mapper.selectByExample(example));
        if (!characterOptional.isPresent()) {
            throw new ServiceException("你还未设置角色");
        }
        return characterWithFullData(characterOptional.get());
    }

    private CharacterData characterWithFullData(PlaySceneCharacter character) {
        CharacterData data = new CharacterData();
        data.setCharacterId(character.getCharacterId());
        data.setMemberId(character.getMemberId());

        Integer sceneCharacterId = character.getSceneCharacterId();
        List<ItemSimpleInfo> items = playSceneCharacterItemService.findItemSimpleInfoBySceneCharId(sceneCharacterId);
        List<SkillSimpleInfo> skills = playSceneCharacterSkillService.findSkillSimpleInfoBySceneCharId(sceneCharacterId);
        data.setItems(items);
        data.setSkills(skills);
        return data;
    }

    public List<SimpleCharacterMeta> simpleMeta(Integer sceneId) {
        return Pager.doPageAll(() -> mapper.simpleMeta(sceneId));
    }

    public void copySceneCharacters(Integer playId, Integer sceneId) {
        List<PlayCharacter> allCharacters = playCharacterService.findAllCharacters(playId);
        if (!ArrayUtil.isEmpty(allCharacters)) {
            List<PlaySceneCharacter> sceneCharacters = allCharacters.parallelStream()
                    .map(c -> {
                        PlaySceneCharacter character = new PlaySceneCharacter();
                        character.setCharacterId(c.getCharacterId());
                        character.setSceneId(sceneId);
                        return character;
                    }).collect(toList());
            sceneCharacters.forEach(mapper::insert);
            playSceneCharacterSkillService.copyCharacterSkill(sceneCharacters);
        }
    }

    @Transactional
    public void putMemberCharacter(String mid, Integer sceneId, Integer characterId) {
        hasAnyCharacter(sceneId, mid, true);
        PlaySceneCharacterExample example = new PlaySceneCharacterExample();
        example.createCriteria()
                .andSceneIdEqualTo(sceneId)
                .andCharacterIdEqualTo(characterId);
        Optional<PlaySceneCharacter> characterOptional = Pager.doSingleton(() -> mapper.selectByExample(example));
        if (!characterOptional.isPresent()) {
            throw new ServiceException("角色不存在");
        }
        PlaySceneCharacter updateCharacter = new PlaySceneCharacter();
        updateCharacter.setSceneCharacterId(characterOptional.get().getSceneCharacterId());
        updateCharacter.setMemberId(mid);
        mapper.updateByPrimaryKeySelective(updateCharacter);
    }

    private boolean hasAnyCharacter(Integer sceneId, String mid, boolean needClear) {
        PlaySceneCharacterExample example = new PlaySceneCharacterExample();
        example.createCriteria()
                .andMemberIdEqualTo(mid)
                .andSceneIdEqualTo(sceneId);
        if (needClear) {
            Page<PlaySceneCharacter> characters = Pager.doPageAll(() -> mapper.selectByExample(example));
            boolean hasCharacter = !ArrayUtil.isEmpty(characters);
            if (hasCharacter) {
                characters.forEach(c -> {
                    c.setMemberId(null);
                    mapper.updateByPrimaryKey(c);
                });
            }
            return hasCharacter;
        }else{
            return mapper.countByExample(example) > 0;
        }
    }

}
